%%% server_utils.erl

-module(server_utils).
-export([send_file/2, send_data/2, send_messages/2, accept_file/5, receive_file/3, next_worker/1, receive_data/2, 
         open_socket/1, close_socket/1, create_id/0, create_name/2, split_tasks/1, get_extension/1, get_process_name/1]).

send_file(Socket, File_Data) ->
	Data_Length  = length(integer_to_list(byte_size(File_Data), 2)),
	Data_To_Send = list_to_binary(binary_to_list(<<Data_Length:32>>) ++ binary_to_list(File_Data)),
	ok = gen_tcp:send(Socket, Data_To_Send).

receive_file(Socket, File_Name, compressed) ->
	{ok, Data}    = gen_tcp:recv(Socket, 0),
	Data_To_Write = list_to_binary(string:substr(binary_to_list(Data), 5)),
	ok = file:write_file(File_Name, zlib:uncompress(Data_To_Write));

receive_file(Socket, File_Name, gzipped) ->
	{ok, Data}    = gen_tcp:recv(Socket, 0),
	Data_To_Write = list_to_binary(string:substr(binary_to_list(Data), 5)),
	ok = file:write_file(File_Name, zlib:gunzip(Data_To_Write));

receive_file(Socket, File_Name, zipped) ->
	{ok, Data}    = gen_tcp:recv(Socket, 0),
	Data_To_Write = list_to_binary(string:substr(binary_to_list(Data), 5)),
	ok = file:write_file(File_Name, zlib:unzip(Data_To_Write)).

receive_data(Socket, gzipped) ->
	{ok, Data}     = gen_tcp:recv(Socket, 0),
	Data_To_Return = list_to_binary(string:substr(binary_to_list(Data), 5)),
	{ok, zlib:gunzip(Data_To_Return)};

receive_data(Socket, compressed) ->
	{ok, Data}     = gen_tcp:recv(Socket, 0),
	Data_To_Return = list_to_binary(string:substr(binary_to_list(Data), 5)),
	{ok, zlib:uncompress(Data_To_Return)};

receive_data(Socket, zipped) ->
	{ok, Data}     = gen_tcp:recv(Socket, 0),
	Data_To_Return = list_to_binary(string:substr(binary_to_list(Data), 5)),
	{ok, zlib:unzip(Data_To_Return)}.

open_socket(Socket_Number) ->
	{ok, Listen_Socket}   = gen_tcp:listen(Socket_Number, [binary, {packet, 4}, {active, false}]),
	{ok, {Address, Port}} = inet:sockname(Listen_Socket),
	{Listen_Socket, Address, Port}.

create_id() ->
	{Hr, Min, Sec} = now(), random:seed(Hr, Min, Sec),
	list_to_atom([(random:uniform(26) + 97)] ++ integer_to_list(Hr) ++ integer_to_list(Min) ++ integer_to_list(Sec)).

create_name(Work, Job_ID)  -> list_to_atom(atom_to_list(Work) ++ atom_to_list(Job_ID)).
split_tasks(Tasks)         -> string:tokens(binary:bin_to_list(Tasks), "\n"). %TODO change to create a dictionary
next_worker(Worker_Number) -> list_to_atom("worker" ++ integer_to_list(Worker_Number+1)).

accept_file({Type, Ext}, Job_ID, Socket, Client, Client_Proc) ->
    send_messages({Client, Client_Proc}, [ready]),
	Filename = list_to_atom(atom_to_list(Job_ID) ++ Type ++ "." ++ Ext),
	receive_file(Socket, Filename, zipped),
    send_messages({Client, Client_Proc}, [{finished, ok}]),
	{true, Filename}.

receive_info(ready) ->
	receive
		ready ->
			{ok, {ready, send}};
		Message ->
			{error, {Message}}
	end.
